package com.mhc.suzuki.service.impl;

import com.mhc.suzuki.bo.LocationBO;
import com.mhc.suzuki.dal.mapper.IdCardLocationMapper;
import com.mhc.suzuki.dal.mapper.ext.MobileAreaExtMapper;
import com.mhc.suzuki.dal.model.IdCardLocationDO;
import com.mhc.suzuki.dal.query.IdCardLocationQuery;
import com.mhc.suzuki.exception.SuzukiCommonException;
import com.mhc.suzuki.service.LocationService;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.regex.Pattern;


/**
 * Created by HW
 * on 2017/8/31 18:47.
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class LocationServiceImpl implements LocationService {

    @Autowired
    private MobileAreaExtMapper mobileAreaExtMapper;

    @Autowired
    private IdCardLocationMapper idCardLocationMapper;


    /**
     * 根据手机号获取对应归属地
     * @param mobilePhone
     * @return
     */
    @Override
    public String getLocation(String mobilePhone) throws SuzukiCommonException{
        String result = "";
        if (StringUtils.isBlank(mobilePhone) || mobilePhone.length() < 7){
            return result;
        }

        String  topSeven = mobilePhone.substring(0, 7);
        log.info(topSeven);
        result = mobileAreaExtMapper.getLocation(topSeven);
        return result;
    }


    /**
     * 根据身份证获取相关信息
     * @param idCard
     * @return
     */
    @Override
    public LocationBO getIdCardInfo(String idCard) {
        LocationBO locationBO = new LocationBO();

        String myRegExpIDCardNo = "^\\d{6}(((19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9]|x|X))|(\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}))$";
        boolean valid = Pattern.matches(myRegExpIDCardNo, idCard) || (idCard.length() == 17 && Pattern.matches(myRegExpIDCardNo, idCard.substring(0, 15)));
        if (!valid) {
            locationBO.setResult(Boolean.FALSE);
            return locationBO;
        }

        String topSix = idCard.substring(0, 6);
        IdCardLocationQuery idCardLocationQuery = new IdCardLocationQuery();
        idCardLocationQuery.createCriteria().andIdCodeEqualTo(topSix);
        List<IdCardLocationDO> idCardLocationDOS = idCardLocationMapper.selectByQuery(idCardLocationQuery);
        if(idCardLocationDOS.size() == 1){
            //数据库中有对应身份证记录
            locationBO.setLocation(idCardLocationDOS.get(0).getIdCardLocation());
        } else {
            try {
                String location = this.locationApi(idCard);
                //将缺失数据存入数据库中
                if (location != null){
                    IdCardLocationDO idCardLocationDO = new IdCardLocationDO();
                    idCardLocationDO.setIdCardLocation(location);
                    idCardLocationDO.setIdCode(topSix);
                    idCardLocationMapper.insertSelective(idCardLocationDO);
                    locationBO.setLocation(location);
                } else {
                    locationBO.setLocation("身份证格式有误");
                }
            } catch (Exception e){
                log.error(e.getMessage(), e);
                locationBO.setLocation("身份证调用api出错");
            }
        }



        //性别设置
        int idxSexStart = 16;
        int birthYearSpan = 4;
        //如果是15位的证件号码
        if(idCard.length() == 15) {
            idxSexStart = 14;
            birthYearSpan = 2;
        }

        //性别
        String idxSexStr = idCard.substring(idxSexStart, idxSexStart + 1);
        int sex = Integer.parseInt(idxSexStr) % 2 ^ 1;
        locationBO.setSex(sex);//性别设置

        //出生日期
        String year = (birthYearSpan == 2 ? "19" : "") + idCard.substring(6, 6 + birthYearSpan);
        String month = idCard.substring(6 + birthYearSpan, 6 + birthYearSpan + 2);
        String day = idCard.substring(8 + birthYearSpan, 8 + birthYearSpan + 2);
        String birthday = year + '-' + month + '-' + day;

        LocalDate birth = LocalDate.parse(birthday);

        locationBO.setBirth(birth);
        locationBO.setResult(Boolean.TRUE);
        return locationBO;
    }


    /**
     * 调用外部接口查询身份证归属地
     * @param idCard
     */
    private String locationApi(String idCard) throws SuzukiCommonException, IOException{
        String location = null;
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost= new HttpPost("http://api.46644.com/idcard?idcard=" + idCard);
        // Create a custom response handler
        ResponseHandler<JSONObject> responseHandler = response->{
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 && status < 300) {
                //获得调用成功后  返回的数据
                HttpEntity entity = response.getEntity();
                if(null!=entity){
                    String result= EntityUtils.toString(entity);
                    //根据字符串生成JSON对象
                    return JSONObject.fromObject(result);
                }else{
                    return null;
                }
            } else {
                throw new ClientProtocolException("Unexpected response status: " + status);
            }
        };

        //返回的json对象
        JSONObject responseBody = httpclient.execute(httpPost, responseHandler);

        if (responseBody.has("address")){
            location = responseBody.get("address").toString().replaceAll(" ", "");
            log.info("location:{}",location);
        }
        return location;
    }

}
